<?php 
/*
 * emarket - a website to create your own online-shop.  
 * Copyright (C) 2009  Frédéric Delorme
 *
 * This file is part of emarket.
 *
 * emarket is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * emarket is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with emarket.  If not, see <http://www.gnu.org/licenses/>.
 *
 * To contact me: frederic.delorme@gmail.com
 * to see some information on te project : http://code.google.col/p/os-emarket/
 *
 */
global $framework;
require_once($framework."/persistence/datapersistence.php");
require_once($framework."/persistence/datafile.php");
require_once($framework."/persistence/datamysql.php");

class Data{
	/**
	 * instance for Data.
	 * @var Data instance.
	 */
	static private $_instance = null;
	
	protected $pagesize		= 20;
	protected $pageoffset	= 0;
	
	/**
	 * Datamanager to be implemented by this version.
	 * @var DataPersistence implementation
	 */
	private $datamanager = null;
	
	/**
	 * Default constructor.
	 */
	public function __construct(){
		$type = __param("database","type");
		switch($type){
			case "mysql":
				$this->datamanager = new DataMySQL();
				break;
			case "file":
				$this->datamanager = new DataFile();
				break;
		}
	}
	
	/**
	 * <p>Compose the String containing the Where clause for the SQL request, 
	 * based on an array of criteria.</p>
	 * @param $where <p>Each criteria contains 3 values: <pre>field</pre>, <pre>comparator</pre> and <pre>value</pre>:</p>
	 * <dl>
	 * 	<dt>field</dt>
	 * 	<dd>the name of the field where to apply clause.</dd>
	 * 	<dt>comparator</dt>
	 * 	<dd>any validated comparator for your database implementation ('=','>','<','like','!=', etc...)</dd>
	 * 	<dt>value</dt>
	 * 	<dd>The value to be compared.</dd>
	 * </ul>
	 * <p>example: </p>
	 * <pre>
	 * $where=array(
	 *   array('field'=>"field1",'comparator'=>">",'value'=>"120"),
	 *   array('field'=>"field2",'comparator'=>"<",'value'=>"120"),
	 *   array('field'=>"field3",'comparator'=>"=",'value'=>"120"),
	 *   array('field'=>"field4",'comparator'=>"!=",'value'=>"120"),
	 *   </pre>
	 * @return String containing the where clause.
	 */
	protected function whereString($where=""){
		$swhere="";
		if($where!=""){
			$swhere	= " where ";
			foreach($where as $whereclause){
				$swhere.=$whereclause['field']." ".$whereclause['comparator']." '".$whereclause['value']."'";
			}
		}
		return $swhere;
	}
	
	/**
	 * Compose the Sort Order String for the SQL query.
	 * @param $sortorder <p>is an array of sort order.</p>
	 * <p>Each sort order array must contains 2 values:</p>
	 * <dl>
	 * 	<dt>field</dt>
	 * 	<dl>The field where the sort must be applied.</dl>
	 * 	<dt>direction</dt>
	 * 	<dl>Can be <pre>ASC</pre> for ascending sort of <pre>DESC</pre> for descending sort.</dl>
	 * </dl>
	 * <p>example:</p>
	 * <pre>
	 * $sortorder=
	 * 	array(
	 * 		array('field'=>"created_at",'direction'=>"ASC")),
	 * 		array('field'=>"title",'direction'=>"DESC"))
	 * 	)
	 * </pre>
	 * <p>In the previous sample, the request will sort data according to the 
	 * 	<ul>
	 * 		<li><pre>created_at</pre> (Date) in an ascending order,</li>
	 * 		<li><pre>title</pre> (String) in a descending order.</li>
	 * 	</ul>
	 * @return Strring containing the Sort order clause.
	 */
	protected function sortString($sortorder=""){
		$ssortorder="";	
		if($sortorder!=""){
			$ssortorder	= " order by ";
			foreach($sortorder as $sort){
				$ssortorder.=$sort['field']." ".$sort['direction'];
			}
		}
		return $ssortorder;
	} 
		
	/**
	 * return the corresponding instance.
	 * @return unknown_type
	 */
	public function getInstance(){
		if(empty(self::$_instance)){
			self::$_instance = new Data();
		}
		return self::$_instance;
	}
	/**
	 * Return the configured instanciate manager.
	 * @return IData.
	 */
	public function getManager(){
		return $this->datamanager;
	}
	
	/**
 	 * Retrieve and require the needed class.
	 * @param $type
	 * @return unknown_type
	 */
	protected function requireEntity($type){
		global $framework;
		__debug(__CLASS__."::requireEntity() - start",__FILE__,__LINE__);
		if($type == "parameter"){
			__debug(__CLASS__."::requireEntity() - internal type : ".ucfirst($type),__FILE__,__LINE__);
			require_once($framework."/entities/$type.entity.php");
		}else{
			__debug(__CLASS__."::requireEntity() - user type : ".ucfirst($type),__FILE__,__LINE__);
			require_once("webapp/entities/$type.entity.php");
		}
	}
	
}
/**
 * helper to get a group of entities
 * @param $type string the type of entity to retrieve.
 * @return array following this description: array('id_value'=>array( 'id'=> id_value, ...),...)
 */
function __entities($type){
	$data = Data::getInstance();
	return $data->getManager()->getEntities($type);
}
/**
 * helper to get one entity
 * @param $type string the type of entity to retrieve.
 * @param $id string the id of entity to retrieve.
 * @return array following this description: array( 'id'=> id_value, ...)
 */
function __entity($entitytype,$id){
	$data = Data::getInstance();
	return $data->getManager()->getEntity($entitytype,$id);
}

/**
 * <p>Retrieve entity for the given $type and $id, and the associates entity of type $associates.</p>
 * @param $entitytype Type of entity.
 * @param $id <p>Unique Identifier for the entity of $type to be retrieved.</p>
 * @param $associates <p><pre>array()</pre> of associated entities to be retrieved.
 * @return array() <p>containing fields of Entity and all the linked entities into 
 * attributes named as follow: entityname+'s'</p>
 * <p><u>example:</u></p>
 * <p>An entity <pre><strong>Post</strong></pre>, composed of a <pre>title</pre>, 
 * a <pre>header</pre>, a <pre>content</pre> and an <pre>author</pre>, 
 * is linked to entity <pre><strong>Resource</strong></pre>, composed of 
 * a <pre>resource_id</pre>, an <pre>url</pre>, a <pre>name</pre>, and a <pre>description</pre>, 
 * in a relation <em>One to Many</em>.
 * The entity <pre>Post</pre> will be retrieved with the following attributes:</p>
 * <pre>
 * $post = array(
 * 	'post_id'	=> 1
 * 	'title'		=> "My Title",
 * 	'header'	=> "The header of this Post...",
 * 	'content'	=> "the content of this post with a lot of lines...",
 *  'author'	=> "John X",
 *  'resources'	=> array(
 *  			'12'=>array(
 *  				'resource_id'	=> 12,
 *  				'url'			=> "path/to/my/resource/12.jpg",
 *  				'name'			=> "My resource 12",
 *  				'description'	=> "A chort description for my resource 12"),
 *  			'13'=>array(
 *  				'resource_id'	=> 13,
 *  				'url'			=> "path/to/my/resource/13.jpg",
 *  				'name'			=> "My resource 13",
 *  				'description'	=> "A chort description for my resource 13")
 *  			)
 * </pre>
 * <p>In the previous sample, there are 2 resources (12 and 13) associates to 
 * the post '1'.</p>
 */
function __entity_associates($entitytype,$id, $associates=""){
	$data = Data::getInstance();
	return $data->getManager()->getEntityAssociates($entitytype, $id, $associates);
}
/**
 * Helper to retrieve data entities according to the $type of entity, the $where clause
 * a $sortorder sort order and a maximum $limit of record to be retrieved.
 * @see IData#queryEntities($type,$where)
 * @param $type
 * @param $where
 * @param $sortorders
 * @param $limit
 * @return unknown_type
 */
function __query_entities($type="",$where="",$sortorders="",$limit=""){
	$data = Data::getInstance();
	return $data->getManager()->queryEntities($type,$where,$sortorders,$limit);
}
/**
 * helper to return a group of system parameters.
 * @param $group name of the group
 * @return array following this description: array('id_value'=>array( 'id'=> id_value, ...),...)
 */
function __sysgrpparam($group){
	$data = Data::getInstance();
	return $data->getManager()->getGroupParams($group);
}
/**
 * helper to get one parameter
 * @param $group string the group name of parameters.
 * @param $key string the key of entity to retrieve.
 * @return string value for the parameter.
 */
function __sysparam($group,$key){
	$data = Data::getInstance();
	return $data->getManager()->getParam($group,$key);
}
?>